package uy.org.softtech.cssuite.entidad.usuario;

import static uy.org.softtech.cssuite.entidad.Entidad.USUARIO_NAMESPACE;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;

import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.annotate.JsonRootName;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;

import uy.org.softtech.cssuite.entidad.EntidadTraducible;

/**
 * <p>Entidad que representa a un permiso asigando a un rol de usuario.</p>
 * 
 * <p>El siguiente fragmento de esquema especifica el contenido esperado y representado por los atributos de esta clase.</p>
 *  
 * <pre>
 * &lt;xsd:complexType name="permiso">
 *  &lt;xsd:all>
 *   &lt;xsd:element name="id" type="xsd:ID"/>
 *   &lt;xsd:element name="token" type="{http://cssuite.softtech.org.uy/esquemas/tipos}token" />
 *   &lt;xsd:element name="tipo" type="{http://cssuite.softtech.org.uy/esquemas/tipos}tipoPermiso" minOccurs="0" />
 *   &lt;xsd:element name="descripcion" type="{http://cssuite.softtech.org.uy/esquemas/tipos}texto" minOccurs="0" />
 *  &lt;/xsd:all>
 * &lt;/xsd:complexType>
 * 
 * </pre>
 *
 * @author fabian.lobo
 */
@Entity
@JsonRootName(value = "permiso")
@JsonSerialize(include = Inclusion.NON_NULL)
@Table(name = "CSS_PERMISO")
@XmlSeeAlso({EntidadTraducible.class})
@XmlType(name = "permiso", namespace = USUARIO_NAMESPACE, propOrder = {})
public class Permiso extends EntidadTraducible implements Serializable {

	private static final long serialVersionUID = 765482314254598370L;
	
	/**
	 * <p>Enumerado para todos los posibles tokens de seguridad</p>
	 * 
	 * <p>El siguiente fragmento de esquema especifica el contenido esperado y representado por los atributos de este enumerado.</p>
	 *  
	 * <pre>
	 * &lt;xsd:simpleType name="token">
	 *  &lt;xsd:restriction base="xsd:string">
	 *   &lt;xsd:enumeration value="CONFIGURACION" />
	 *   &lt;xsd:enumeration value="VER_USUARIOS" />
	 *   &lt;xsd:enumeration value="CREAR_USUARIO" />
	 *   &lt;xsd:enumeration value="ACTUALIZAR_USUARIO" />
	 *   &lt;xsd:enumeration value="BLOQUEAR_USUARIO" />
	 *   &lt;xsd:enumeration value="ELIMINAR_USUARIO" />
	 *   &lt;xsd:enumeration value="VER_SESIONES" />
	 *   &lt;xsd:enumeration value="CERRAR_SESION" />
	 *   &lt;xsd:enumeration value="VER_TAREAS" />
	 *   &lt;xsd:enumeration value="EJECUTAR_TAREA" />
	 *   &lt;xsd:enumeration value="VER_CLIENTES" />
	 *   &lt;xsd:enumeration value="CREAR_CLIENTE" />
	 *   &lt;xsd:enumeration value="ACTUALIZAR_CLIENTE" />
	 *   &lt;xsd:enumeration value="BLOQUEAR_CLIENTE" />
	 *   &lt;xsd:enumeration value="ELIMINAR_CLIENTE" />
	 *   &lt;xsd:enumeration value="VER_CUENTAS" />
	 *   &lt;xsd:enumeration value="CREAR_CUENTA" />
	 *   &lt;xsd:enumeration value="ACTUALIZAR_CUENTA" />
	 *   &lt;xsd:enumeration value="BLOQUEAR_CUENTA" />
	 *   &lt;xsd:enumeration value="CANCELAR_CUENTA" />
	 *   &lt;xsd:enumeration value="CERRAR_CUENTA" />
	 *  &lt;/xsd:restriction>
	 * &lt;/xsd:simpleType>
	 * 
	 * </pre>
	 * 
	 * @author fabian.lobo
	 */
	@XmlEnum
	@XmlType(name = "token", namespace = USUARIO_NAMESPACE)
	public enum Token {
		CONFIGURACION, 
		VER_USUARIOS, CREAR_USUARIO, ACTUALIZAR_USUARIO, BLOQUEAR_USUARIO, ELIMINAR_USUARIO,  
		VER_SESIONES, CERRAR_SESION, 
		VER_TAREAS, EJECUTAR_TAREA,
		VER_CLIENTES, CREAR_CLIENTE, ACTUALIZAR_CLIENTE, BLOQUEAR_CLIENTE, ELIMINAR_CLIENTE,
		VER_CUENTAS, CREAR_CUENTA, ACTUALIZAR_CUENTA, BLOQUEAR_CUENTA, CANCELAR_CUENTA, CERRAR_CUENTA
	}
	
	/**
	 * Enumerado para agrupar los tokens de seguridad
	 * 
	 * @author fabian.lobo
	 */
	@XmlEnum
	@XmlType(name = "tipoPermiso", namespace = USUARIO_NAMESPACE)
	public enum Tipo {
		GENERAL, USUARIOS, SESIONES, TAREAS, CLIENTES, CUENTAS
	}
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "ID_PERMISO")
	@XmlElement(name = "id", namespace = USUARIO_NAMESPACE, required = true)
	private Long id;
	
	@Column(name = "TOKEN", length = 25, nullable = false, unique = true)
	@XmlElement(name = "token", namespace = USUARIO_NAMESPACE, required = true)
	private Token token;
	
	@Column(name = "NOMBRE", length = 30, nullable = false)
	@JsonIgnore
	@XmlTransient
	private String nombre;
	
	@Enumerated(EnumType.STRING)
	@Column(name = "TIPO", nullable = false)
	@XmlElement(name = "tipo", namespace = USUARIO_NAMESPACE, required = true)
	private Tipo tipo;
	
	/*
	 *  GETTERS
	 */
	public Long getId() {
		return id;
	}
	public Token getToken() {
		return token;
	}
	public String getNombre() {
		return nombre;
	}
	public Tipo getTipo() {
		return tipo;
	}

	/*
	 *  SETTERS
	 */
	public void setId(Long id) {
		this.id = id;
	}
	public void setToken(Token token) {
		this.token = token;
	}
	public void setNombre(String nombre) {
		this.nombre = nombre;
	}
	public void setTipo(Tipo tipo) {
		this.tipo = tipo;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 3;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		Permiso other = (Permiso) obj;
		if (id != null && other.id != null && id.equals(other.id)) {
			return true;
		}
		return false;
	}

	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("Permiso [");
		builder.append("id=" + getId() + ", ");
		builder.append("token=" + getToken() + ", ");
		builder.append("nombre=" + getNombre() + ", ");
		builder.append("tipo=" + getTipo());
		builder.append("]");
		return builder.toString();
	}

	@Override
	public String toString(boolean incluirColecciones) {
		StringBuilder result = new StringBuilder(toString());
		
		if(incluirColecciones) {
			//int offset = result.length() - 2;
			//StringBuilder builder = new StringBuilder(", ");
			//builder.append("permissions=" + getPermissions());
			//result.insert(offset, builder.toString());
		}	
				
		return result.toString();
	}

}
